package com.ld.poetry.service.impl;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.LambdaUpdateChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ld.poetry.config.PoetryResult;
import com.ld.poetry.aop.ResourceCheck;
import com.ld.poetry.constants.CommonConst;
import com.ld.poetry.dao.ArticleMapper;
import com.ld.poetry.dao.LabelMapper;
import com.ld.poetry.dao.SortMapper;
import com.ld.poetry.entity.*;
import com.ld.poetry.enums.CommentTypeEnum;
import com.ld.poetry.enums.PoetryEnum;
import com.ld.poetry.service.ArticleService;
import com.ld.poetry.service.UserService;
import com.ld.poetry.utils.*;
import com.ld.poetry.utils.cache.PoetryCache;
import com.ld.poetry.utils.mail.MailUtil;
import com.ld.poetry.vo.ArticleVO;
import com.ld.poetry.vo.BaseRequestVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 文章表 服务实现类
 * </p>
 *
 * @author sara
 * @since 2021-08-13
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements ArticleService {

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private CommonQuery commonQuery;

    @Autowired
    private UserService userService;

    @Autowired
    private MailUtil mailUtil;

    @Autowired
    private SortMapper sortMapper;

    @Autowired
    private LabelMapper labelMapper;

    @Value("${user.subscribe.format}")
    private String subscribeFormat;

    /**
     * 保存文章
     * 
     * 该方法用于保存新文章，包括以下功能：
     * 1. 参数校验：检查私密文章是否设置了密码
     * 2. 设置文章属性：包括标题、内容、状态等
     * 3. 保存文章到数据库
     * 4. 清除相关缓存
     * 5. 发送订阅通知邮件（如果文章是公开的）
     * 
     * @param articleVO 文章信息对象，包含文章的所有属性
     * @return PoetryResult 操作结果，成功时返回成功状态，失败时返回错误信息
     */
    @Override
    public PoetryResult saveArticle(ArticleVO articleVO) {
        // 参数校验：如果是私密文章，必须设置密码
        if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && !StringUtils.hasText(articleVO.getPassword())) {
            return PoetryResult.fail("请设置文章密码！");
        }

        // 创建文章实体对象
        Article article = new Article();
        
        // 设置文章封面，如果有的话
        if (StringUtils.hasText(articleVO.getArticleCover())) {
            article.setArticleCover(articleVO.getArticleCover());
        }
        
        // 设置视频URL，如果有的话
        if (StringUtils.hasText(articleVO.getVideoUrl())) {
            article.setVideoUrl(articleVO.getVideoUrl());
        }
        
        // 如果是私密文章，设置密码和提示信息
        if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && StringUtils.hasText(articleVO.getPassword())) {
            article.setPassword(articleVO.getPassword());
            article.setTips(articleVO.getTips());
        }
        
        // 设置文章的基本属性
        article.setViewStatus(articleVO.getViewStatus());        // 设置文章可见状态
        article.setCommentStatus(articleVO.getCommentStatus());  // 设置评论状态
        article.setRecommendStatus(articleVO.getRecommendStatus()); // 设置推荐状态
        article.setArticleTitle(articleVO.getArticleTitle());    // 设置文章标题
        article.setArticleContent(articleVO.getArticleContent()); // 设置文章内容
        article.setSortId(articleVO.getSortId());               // 设置分类ID
        article.setLabelId(articleVO.getLabelId());             // 设置标签ID
        article.setUserId(PoetryUtil.getUserId());              // 设置作者ID（当前登录用户）

        // 保存文章到数据库
        save(article);

        // 清除分类信息缓存，确保分类信息是最新的
        PoetryCache.remove(CommonConst.SORT_INFO);

        // 发送订阅通知邮件（仅对公开文章）
        try {
            if (articleVO.getViewStatus()) {
                // 获取所有启用的用户
                List<User> users = userService.lambdaQuery()
                    .select(User::getEmail, User::getSubscribe)  // 只查询邮箱和订阅信息
                    .eq(User::getUserStatus, PoetryEnum.STATUS_ENABLE.getCode()) // 只查询启用状态的用户
                    .list();

                // 筛选出订阅了该文章标签的用户
                List<String> emails = users.stream()
                    .filter(u -> {
                        // 解析用户的订阅标签列表
                        List<Integer> sub = JSON.parseArray(u.getSubscribe(), Integer.class);
                        // 检查用户是否订阅了当前文章的标签
                        return !CollectionUtils.isEmpty(sub) && sub.contains(articleVO.getLabelId());
                    })
                    .map(User::getEmail)  // 提取用户的邮箱
                    .collect(Collectors.toList());

                // 如果有订阅用户，发送通知邮件
                if (!CollectionUtils.isEmpty(emails)) {
                    // 获取标签名称
                    Label label = new LambdaQueryChainWrapper<>(labelMapper)
                        .select(Label::getLabelName)
                        .eq(Label::getId, articleVO.getLabelId())
                        .one();
                    
                    // 生成邮件内容
                    String text = getSubscribeMail(label.getLabelName(), articleVO.getArticleTitle());
                    
                    // 获取网站信息
                    WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
                    
                    // 发送邮件
                    mailUtil.sendMailMessage(
                        emails,  // 收件人列表
                        "您有一封来自" + (webInfo == null ? "POETIZE" : webInfo.getWebName()) + "的回执！",  // 邮件主题
                        text     // 邮件内容
                    );
                }
            }
        } catch (Exception e) {
            // 邮件发送失败不影响文章保存，只记录错误日志
            log.error("订阅邮件发送失败：", e);
        }
        
        // 返回成功结果
        return PoetryResult.success();
    }

    private String getSubscribeMail(String labelName, String articleTitle) {
        WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
        String webName = (webInfo == null ? "POETIZE" : webInfo.getWebName());
        return String.format(mailUtil.getMailText(),
                webName,
                String.format(MailUtil.notificationMail, PoetryUtil.getAdminUser().getUsername()),
                PoetryUtil.getAdminUser().getUsername(),
                String.format(subscribeFormat, labelName, articleTitle),
                "",
                webName);
    }

    /**
     * 删除文章
     * 
     * 该方法用于删除指定ID的文章，包括以下功能：
     * 1. 验证文章所有权：只能删除自己的文章
     * 2. 删除文章记录
     * 3. 清除相关缓存
     * 
     * @param id 要删除的文章ID
     * @return PoetryResult 操作结果，成功时返回成功状态
     */
    @Override
    public PoetryResult deleteArticle(Integer id) {
        // 获取当前登录用户ID
        Integer userId = PoetryUtil.getUserId();
        
        // 删除文章（只能删除自己的文章）
        lambdaUpdate()
            .eq(Article::getId, id)           // 匹配文章ID
            .eq(Article::getUserId, userId)   // 匹配作者ID（确保只能删除自己的文章）
            .remove();                        // 执行删除操作

        // 清除分类信息缓存，确保分类信息是最新的
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        // 返回成功结果
        return PoetryResult.success();
    }

    /**
     * 更新文章
     * 
     * 该方法用于更新已存在的文章，包括以下功能：
     * 1. 参数校验：检查私密文章是否设置了密码
     * 2. 验证文章所有权：只能更新自己的文章
     * 3. 更新文章属性：包括标题、内容、状态等
     * 4. 清除相关缓存
     * 
     * @param articleVO 文章信息对象，包含要更新的文章属性
     * @return PoetryResult 操作结果，成功时返回成功状态，失败时返回错误信息
     */
    @Override
    public PoetryResult updateArticle(ArticleVO articleVO) {
        // 参数校验：如果是私密文章，必须设置密码
        if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && !StringUtils.hasText(articleVO.getPassword())) {
            return PoetryResult.fail("请设置文章密码！");
        }

        // 获取当前登录用户ID
        Integer userId = PoetryUtil.getUserId();
        
        // 创建更新条件构建器
        LambdaUpdateChainWrapper<Article> updateChainWrapper = lambdaUpdate()
            .eq(Article::getId, articleVO.getId())           // 匹配文章ID
            .eq(Article::getUserId, userId)                  // 匹配作者ID（确保只能更新自己的文章）
            .set(Article::getLabelId, articleVO.getLabelId()) // 更新标签ID
            .set(Article::getSortId, articleVO.getSortId())   // 更新分类ID
            .set(Article::getArticleTitle, articleVO.getArticleTitle()) // 更新文章标题
            .set(Article::getUpdateBy, PoetryUtil.getUsername()) // 设置更新人
            .set(Article::getUpdateTime, LocalDateTime.now())    // 设置更新时间
            .set(Article::getVideoUrl, StringUtils.hasText(articleVO.getVideoUrl()) ? articleVO.getVideoUrl() : null) // 更新视频URL
            .set(Article::getArticleContent, articleVO.getArticleContent()); // 更新文章内容

        // 更新文章封面（如果有）
        if (StringUtils.hasText(articleVO.getArticleCover())) {
            updateChainWrapper.set(Article::getArticleCover, articleVO.getArticleCover());
        }
        
        // 更新评论状态（如果有）
        if (articleVO.getCommentStatus() != null) {
            updateChainWrapper.set(Article::getCommentStatus, articleVO.getCommentStatus());
        }
        
        // 更新推荐状态（如果有）
        if (articleVO.getRecommendStatus() != null) {
            updateChainWrapper.set(Article::getRecommendStatus, articleVO.getRecommendStatus());
        }
        
        // 如果是私密文章，更新密码和提示信息
        if (articleVO.getViewStatus() != null && !articleVO.getViewStatus() && StringUtils.hasText(articleVO.getPassword())) {
            updateChainWrapper.set(Article::getPassword, articleVO.getPassword());
            updateChainWrapper.set(StringUtils.hasText(articleVO.getTips()), Article::getTips, articleVO.getTips());
        }
        
        // 更新文章可见状态（如果有）
        if (articleVO.getViewStatus() != null) {
            updateChainWrapper.set(Article::getViewStatus, articleVO.getViewStatus());
        }
        
        // 执行更新操作
        updateChainWrapper.update();

        // 清除分类信息缓存，确保分类信息是最新的
        PoetryCache.remove(CommonConst.SORT_INFO);
        
        // 返回成功结果
        return PoetryResult.success();
    }

    /**
     * 获取文章列表
     * 
     * 该方法用于获取文章列表，支持以下功能：
     * 1. 文章搜索：支持标题搜索和内容搜索
     * 2. 分类筛选：按分类ID筛选
     * 3. 标签筛选：按标签ID筛选
     * 4. 推荐筛选：筛选推荐文章
     * 5. 结果处理：处理文章内容摘要、视频信息等
     * 
     * @param baseRequestVO 请求参数对象，包含分页、搜索、筛选等信息
     * @return PoetryResult<Page> 分页的文章列表
     */
    @Override
    public PoetryResult<Page> listArticle(BaseRequestVO baseRequestVO) {
        // 初始化文章ID列表
        List<Integer> ids = null;
        List<List<Integer>> idList = null;
        
        // 如果有关键词搜索，获取匹配的文章ID
        if (StringUtils.hasText(baseRequestVO.getArticleSearch())) {
            idList = commonQuery.getArticleIds(baseRequestVO.getArticleSearch());
            ids = idList.stream().flatMap(Collection::stream).collect(Collectors.toList());
            // 如果没有找到匹配的文章，返回空结果
            if (CollectionUtils.isEmpty(ids)) {
                baseRequestVO.setRecords(new ArrayList<>());
                return PoetryResult.success(baseRequestVO);
            }
        }

        // 构建查询条件
        LambdaQueryChainWrapper<Article> lambdaQuery = lambdaQuery();
        
        // 添加搜索条件
        lambdaQuery.in(!CollectionUtils.isEmpty(ids), Article::getId, ids);  // 按ID筛选
        lambdaQuery.like(StringUtils.hasText(baseRequestVO.getSearchKey()), Article::getArticleTitle, baseRequestVO.getSearchKey());  // 标题模糊搜索
        lambdaQuery.eq(baseRequestVO.getRecommendStatus() != null && baseRequestVO.getRecommendStatus(), Article::getRecommendStatus, PoetryEnum.STATUS_ENABLE.getCode());  // 推荐状态筛选

        // 添加分类或标签筛选条件
        if (baseRequestVO.getLabelId() != null) {
            lambdaQuery.eq(Article::getLabelId, baseRequestVO.getLabelId());  // 按标签筛选
        } else if (baseRequestVO.getSortId() != null) {
            lambdaQuery.eq(Article::getSortId, baseRequestVO.getSortId());    // 按分类筛选
        }

        // 按创建时间倒序排序
        lambdaQuery.orderByDesc(Article::getCreateTime);

        // 执行分页查询
        Page<Article> page = new Page<>(baseRequestVO.getCurrent(), baseRequestVO.getSize());
        lambdaQuery.page(page);

        // 处理查询结果
        List<Article> records = page.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            List<ArticleVO> articles = new ArrayList<>();    // 普通文章列表
            List<ArticleVO> titles = new ArrayList<>();      // 标题匹配的文章列表
            List<ArticleVO> contents = new ArrayList<>();    // 内容匹配的文章列表

            // 处理每篇文章
            for (Article article : records) {
                // 处理文章内容摘要
                if (article.getArticleContent().length() > CommonConst.SUMMARY) {
                    article.setArticleContent(article.getArticleContent()
                        .substring(0, CommonConst.SUMMARY)
                        .replace("`", "")
                        .replace("#", "")
                        .replace(">", ""));
                }
                
                // 构建文章VO对象
                ArticleVO articleVO = buildArticleVO(article, false);
                articleVO.setHasVideo(StringUtils.hasText(articleVO.getVideoUrl()));  // 设置是否有视频
                articleVO.setPassword(null);  // 清空密码
                articleVO.setVideoUrl(null);  // 清空视频URL

                // 根据搜索类型分类文章
                if (CollectionUtils.isEmpty(ids)) {
                    articles.add(articleVO);
                } else if (idList.get(0).contains(articleVO.getId())) {
                    titles.add(articleVO);
                } else if (idList.get(1).contains(articleVO.getId())) {
                    contents.add(articleVO);
                }
            }

            // 合并所有文章列表
            List<ArticleVO> collect = new ArrayList<>();
            collect.addAll(articles);
            collect.addAll(titles);
            collect.addAll(contents);
            page.setRecords(collect);
        }
        
        return PoetryResult.success(page);
    }

    /**
     * 根据ID获取文章详情
     * 
     * 该方法用于获取指定ID的文章详情，包括以下功能：
     * 1. 文章访问权限控制：私密文章需要密码验证
     * 2. 文章访问统计：更新文章访问次数
     * 3. 视频URL加密：对视频URL进行加密处理
     * 4. 敏感信息处理：清除文章密码
     * 
     * @param id 文章ID
     * @param password 文章密码（如果是私密文章）
     * @return PoetryResult<ArticleVO> 文章详情，包含文章的所有信息
     */
    @Override
    @ResourceCheck(CommonConst.RESOURCE_ARTICLE_DOC)
    public PoetryResult<ArticleVO> getArticleById(Integer id, String password) {
        // 构建查询条件
        LambdaQueryChainWrapper<Article> lambdaQuery = lambdaQuery();
        lambdaQuery.eq(Article::getId, id);  // 按ID查询

        // 获取文章
        Article article = lambdaQuery.one();
        if (article == null) {
            return PoetryResult.success();  // 文章不存在，返回空结果
        }

        // 检查文章访问权限
        if (!article.getViewStatus() && (!StringUtils.hasText(password) || !password.equals(article.getPassword()))) {
            // 如果是私密文章且密码错误，返回错误信息
            return PoetryResult.fail("密码错误" + (StringUtils.hasText(article.getTips()) ? article.getTips() : "请联系作者获取密码"));
        }

        // 更新文章访问次数
        articleMapper.updateViewCount(id);

        // 清除敏感信息
        article.setPassword(null);  // 清除文章密码

        // 加密视频URL
        if (StringUtils.hasText(article.getVideoUrl())) {
            article.setVideoUrl(SecureUtil.aes(CommonConst.CRYPOTJS_KEY.getBytes(StandardCharsets.UTF_8))
                .encryptBase64(article.getVideoUrl()));
        }

        // 构建文章VO对象
        ArticleVO articleVO = buildArticleVO(article, false);
        
        return PoetryResult.success(articleVO);
    }

    /**
     * 获取管理员文章列表
     * 
     * 该方法用于获取管理员可见的文章列表，包括以下功能：
     * 1. 权限控制：根据用户权限显示不同范围的文章
     * 2. 文章筛选：支持按用户ID、标题、推荐状态筛选
     * 3. 分类筛选：支持按分类ID和标签ID筛选
     * 4. 结果处理：处理文章内容、敏感信息等
     * 
     * @param baseRequestVO 请求参数对象，包含分页、搜索、筛选等信息
     * @param isBoss 是否为超级管理员（可以查看所有文章）
     * @return PoetryResult<Page> 分页的文章列表
     */
    @Override
    public PoetryResult<Page> listAdminArticle(BaseRequestVO baseRequestVO, Boolean isBoss) {
        // 构建查询条件
        LambdaQueryChainWrapper<Article> lambdaQuery = lambdaQuery();
        
        // 只查询必要的字段，排除文章内容
        lambdaQuery.select(Article.class, a -> !a.getColumn().equals("article_content"));

        // 权限控制：如果不是超级管理员，只能查看自己的文章
        if (!isBoss) {
            lambdaQuery.eq(Article::getUserId, PoetryUtil.getUserId());  // 只查询当前用户的文章
        } else {
            // 超级管理员可以按用户ID筛选
            if (baseRequestVO.getUserId() != null) {
                lambdaQuery.eq(Article::getUserId, baseRequestVO.getUserId());
            }
        }

        // 添加搜索条件
        if (StringUtils.hasText(baseRequestVO.getSearchKey())) {
            lambdaQuery.like(Article::getArticleTitle, baseRequestVO.getSearchKey());  // 标题模糊搜索
        }
        
        // 添加推荐状态筛选
        if (baseRequestVO.getRecommendStatus() != null && baseRequestVO.getRecommendStatus()) {
            lambdaQuery.eq(Article::getRecommendStatus, PoetryEnum.STATUS_ENABLE.getCode());  // 筛选推荐文章
        }

        // 添加分类筛选
        if (baseRequestVO.getLabelId() != null) {
            lambdaQuery.eq(Article::getLabelId, baseRequestVO.getLabelId());  // 按标签筛选
        }

        // 添加分类筛选
        if (baseRequestVO.getSortId() != null) {
            lambdaQuery.eq(Article::getSortId, baseRequestVO.getSortId());  // 按分类筛选
        }

        // 按创建时间倒序排序并分页
        Page<Article> page = new Page<>(baseRequestVO.getCurrent(), baseRequestVO.getSize());
        lambdaQuery.orderByDesc(Article::getCreateTime).page(page);

        // 处理查询结果
        List<Article> records = page.getRecords();
        if (!CollectionUtils.isEmpty(records)) {
            // 转换为VO对象并处理敏感信息
            List<ArticleVO> collect = records.stream()
                .map(article -> {
                    article.setPassword(null);  // 清除文章密码
                    ArticleVO articleVO = buildArticleVO(article, true);  // 构建VO对象
                    return articleVO;
                })
                .collect(Collectors.toList());
            
            page.setRecords(collect);
        }
        
        return PoetryResult.success(page);
    }

    /**
     * 获取用户自己的文章详情
     * 
     * 该方法用于获取当前登录用户自己的文章详情，包括以下功能：
     * 1. 权限验证：只能查看自己的文章
     * 2. 文章存在性检查：确保文章存在
     * 3. 数据转换：将Article实体转换为ArticleVO对象
     * 
     * @param id 文章ID
     * @return PoetryResult<ArticleVO> 文章详情，包含文章的所有信息
     */
    @Override
    public PoetryResult<ArticleVO> getArticleByIdForUser(Integer id) {
        // 构建查询条件：按文章ID和用户ID查询
        LambdaQueryChainWrapper<Article> lambdaQuery = lambdaQuery();
        lambdaQuery.eq(Article::getId, id)                    // 匹配文章ID
                  .eq(Article::getUserId, PoetryUtil.getUserId());  // 匹配当前用户ID

        // 获取文章
        Article article = lambdaQuery.one();
        if (article == null) {
            return PoetryResult.fail("文章不存在！");  // 文章不存在，返回错误信息
        }

        // 构建文章VO对象
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(article, articleVO);  // 复制属性

        return PoetryResult.success(articleVO);
    }

    /**
     * 获取分类文章列表
     * 
     * 该方法用于获取按分类组织的文章列表，包括以下功能：
     * 1. 缓存处理：优先从缓存获取数据
     * 2. 分类文章查询：获取每个分类下的最新文章
     * 3. 文章处理：处理文章内容摘要、视频信息等
     * 4. 结果缓存：将结果存入缓存
     * 
     * @return PoetryResult<Map<Integer, List<ArticleVO>>> 分类文章列表，key为分类ID，value为该分类下的文章列表
     */
    @Override
    public PoetryResult<Map<Integer, List<ArticleVO>>> listSortArticle() {
        // 尝试从缓存获取数据
        Map<Integer, List<ArticleVO>> result = (Map<Integer, List<ArticleVO>>) PoetryCache.get(CommonConst.SORT_ARTICLE_LIST);
        if (result != null) {
            return PoetryResult.success(result);  // 缓存命中，直接返回
        }

        // 使用同步块防止并发问题
        synchronized (CommonConst.SORT_ARTICLE_LIST.intern()) {
            // 双重检查，防止重复查询
            result = (Map<Integer, List<ArticleVO>>) PoetryCache.get(CommonConst.SORT_ARTICLE_LIST);
            if (result == null) {
                // 创建结果Map
                Map<Integer, List<ArticleVO>> map = new HashMap<>();

                // 获取所有分类
                List<Sort> sorts = new LambdaQueryChainWrapper<>(sortMapper)
                    .select(Sort::getId)  // 只查询ID字段
                    .list();

                // 遍历每个分类
                for (Sort sort : sorts) {
                    // 查询该分类下的最新6篇文章
                    LambdaQueryChainWrapper<Article> lambdaQuery = lambdaQuery()
                        .eq(Article::getSortId, sort.getId())  // 按分类ID筛选
                        .orderByDesc(Article::getCreateTime)   // 按创建时间倒序
                        .last("limit 6");                      // 限制6条记录

                    List<Article> articleList = lambdaQuery.list();
                    if (CollectionUtils.isEmpty(articleList)) {
                        continue;  // 该分类下没有文章，跳过
                    }

                    // 处理文章列表
                    List<ArticleVO> articleVOList = articleList.stream()
                        .map(article -> {
                            // 处理文章内容摘要
                            if (article.getArticleContent().length() > CommonConst.SUMMARY) {
                                article.setArticleContent(article.getArticleContent()
                                    .substring(0, CommonConst.SUMMARY)
                                    .replace("`", "")
                                    .replace("#", "")
                                    .replace(">", ""));
                            }

                            // 构建文章VO对象
                            ArticleVO vo = buildArticleVO(article, false);
                            vo.setHasVideo(StringUtils.hasText(article.getVideoUrl()));  // 设置是否有视频
                            vo.setPassword(null);  // 清空密码
                            vo.setVideoUrl(null);  // 清空视频URL
                            return vo;
                        })
                        .collect(Collectors.toList());

                    // 将文章列表存入Map
                    map.put(sort.getId(), articleVOList);
                }

                // 将结果存入缓存
                PoetryCache.put(CommonConst.SORT_ARTICLE_LIST, map, CommonConst.TOKEN_INTERVAL);
                return PoetryResult.success(map);
            } else {
                return PoetryResult.success(result);
            }
        }
    }

    /**
     * 构建文章VO对象
     * 
     * 该方法用于将Article实体转换为ArticleVO对象，包括以下功能：
     * 1. 属性复制：复制基本属性
     * 2. 封面处理：处理文章封面
     * 3. 用户信息：添加作者信息
     * 4. 评论统计：统计文章评论数
     * 5. 分类标签：添加分类和标签信息
     * 
     * @param article 文章实体对象
     * @param isAdmin 是否为管理员操作
     * @return ArticleVO 文章VO对象
     */
    private ArticleVO buildArticleVO(Article article, Boolean isAdmin) {
        // 创建VO对象并复制基本属性
        ArticleVO articleVO = new ArticleVO();
        BeanUtils.copyProperties(article, articleVO);

        // 处理文章封面
        if (!isAdmin) {
            // 非管理员操作时，如果没有封面则生成随机封面
            if (!StringUtils.hasText(articleVO.getArticleCover())) {
                articleVO.setArticleCover(PoetryUtil.getRandomCover(articleVO.getId().toString()));
            }
        }

        // 添加作者信息
        User user = commonQuery.getUser(articleVO.getUserId());
        if (user != null && StringUtils.hasText(user.getUsername())) {
            articleVO.setUsername(user.getUsername());  // 设置作者用户名
        } else if (!isAdmin) {
            // 非管理员操作且没有作者信息时，生成随机用户名
            articleVO.setUsername(PoetryUtil.getRandomName(articleVO.getUserId().toString()));
        }

        // 统计评论数
        if (articleVO.getCommentStatus()) {
            // 如果允许评论，统计评论数量
            articleVO.setCommentCount(commonQuery.getCommentCount(
                articleVO.getId(), 
                CommentTypeEnum.COMMENT_TYPE_ARTICLE.getCode()
            ));
        } else {
            articleVO.setCommentCount(0);  // 不允许评论，评论数为0
        }

        // 添加分类和标签信息
        List<Sort> sortInfo = commonQuery.getSortInfo();
        if (!CollectionUtils.isEmpty(sortInfo)) {
            // 遍历分类列表，查找匹配的分类
            for (Sort s : sortInfo) {
                if (s.getId().intValue() == articleVO.getSortId().intValue()) {
                    // 复制分类信息
                    Sort sort = new Sort();
                    BeanUtils.copyProperties(s, sort);
                    sort.setLabels(null);  // 清除标签列表
                    articleVO.setSort(sort);

                    // 处理标签信息
                    if (!CollectionUtils.isEmpty(s.getLabels())) {
                        // 遍历标签列表，查找匹配的标签
                        for (int j = 0; j < s.getLabels().size(); j++) {
                            Label l = s.getLabels().get(j);
                            if (l.getId().intValue() == articleVO.getLabelId().intValue()) {
                                // 复制标签信息
                                Label label = new Label();
                                BeanUtils.copyProperties(l, label);
                                articleVO.setLabel(label);
                                break;
                            }
                        }
                    }
                    break;
                }
            }
        }

        return articleVO;
    }
}
